/*
 * THE FOLLOWING FIRMWARE IS PROVIDED: 
 *  (1) "AS IS" WITH NO WARRANTY; 
 *  (2) TO ENABLE ACCESS TO CODING INFORMATION TO GUIDE AND FACILITATE CUSTOMER.
 * CONSEQUENTLY, HopeRF SHALL NOT BE HELD LIABLE FOR ANY DIRECT, INDIRECT OR
 * CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING FROM THE CONTENT
 * OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE CODING INFORMATION
 * CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
 * 
 * Copyright (C) HopeRF
 *
 * website: www.HopeRF.com
 *          www.HopeRF.cn     
 */

/*! 
 * file       HopeDuino_CMT221xA.cpp
 * brief      driver for CMT221xA 
 * hardware   HopeDuino with RFM21x
 *            
 *
 * version    1.0
 * date       Feb 18 2016
 * author     QY Ruan
 */
 
#include <HopeDuino_CMT221xA.h>
 

chipsetType Chipset;						//Chipset part number
decodeType Decode;
word SymbolTime;							//one bit time???   unit: us  Range: 10 - 4000
/**********************************************************
**Name:     vCMT221xAInit
**Function: Init. CMT221xA
**Input:    none
**Output:   none
**********************************************************/

// void setup()
// {
//  radio.Chipset        = CMT2210A;
//  radio.SymbolTime     = 416;
//  radio.Decode         = E527; 
//  radio.vCMT221xAInit();
//  uart.vUartInit(9600, _8N1);
// }
void HopeDuino_Setup( void )
{
	TIMx_Int_Init(TIM2,1,1,0xFFFF,36-1); /*for 1us tick */
} 

byte HopeDuino_Start_Cnt( void )
{
	TIM_SetCounter(TIM2,0x0000);
	TIM_Cmd(TIM2, ENABLE);   
	return 0;
}
word HopeDuino_Stop_Cnt( void )
{
	word temp;
	temp = TIM_GetCounter(TIM2);
	TIM_Cmd(TIM2, ENABLE);   
	return temp;
}
/**********************************************************
**Name:     bDecode_EPWM
**Function: decode epwm format 
**Input:    signal pin 
**Output:   data
**********************************************************/
// byte bDecode_EPWM( bool signal_in)
// {
// 	bool last_level; //last signal level 
// 	byte buff[10];
// 	last_level = signal_in;
// 	HopeDuino_Start_Cnt();
// 		return buff;
// }	
/**********************************************************
**Name:     bGetMessage
**Function: receive message
**Input:    msg, array pointer, pklen 
**Output:   msg. length, and zero mean nothing 
**********************************************************/
byte bGetMessage(byte msg[], byte pklen)
{
 byte length=0;
 word count;
 word limit;
 word llim;
 byte rate;
 word bitcnt;
 word det_h;
 word det_l;
 byte i;

 word bitTemp;
 byte ret;	/*return data, data validity*/
 byte rxBits,rxByte;
 byte DataLevelLast;
 ret = 0;
 SymbolTime 	= 416;	/*  */
 SymbolTime 	= 480 ;	/* us */
 Chipset        = CMT2210A;
 Decode         = EPWM; 

halSpiStrobe(CCxxx0_SRX);		//进入接收状态
//delay(5);
//while (!GDO1);
//while (GDO1);
delay(2);
// while (GDO0)
// {
// 	delay(2);
// 	// --i;
// 	// if(i<1)
// 	// 	return 0; 	    
// }	 
// if ((halSpiReadStatus(CCxxx0_RXBYTES) & BYTES_IN_RXFIFO)) //如果接的字节数不为0
{

 if( DATA_H() )				//Low Active
 	{
 	rate  = 8;	
	// rate = 32;			
 	// limit = SymbolTime<<1;	//detect sync for 4*SymbolTime 	
 	limit =  (SymbolTime>>3) >>1;	//because rate=8us; 0.5 symbol time?
	rxBits = 0;
	rxByte = 0;

 	switch( Decode )
 		{
		case EPWM:	/* 脉冲宽度编码， 2symbolTime for 1, 2symboltime for 0*/
		/* */
		for(rxByte = 0;rxByte < 9;)
		{
			DataLevelLast = DATA_READ();
			
			for(count=0; count<10*limit; count++)	/* limit == 10*0.5 symboltime*/
 				{
 				if( DataLevelLast  != DATA_READ())/*  one edge   */
					{
						break;
						//  rxBits++;
					}
					vDelayUs(rate);	/* */
 				}
 			if(count<limit)	//not enough
 				return(0);
			else if(count < 3*limit )	/*1.5symboltime, data "0" */
			{		
				msg[rxByte] &= 0xFF^(0x01<<rxBits);
				rxBits ++;
			}
			else if(count < 5*limit) /*2.5symboltime,data"1" */
			{
				msg[rxByte] |= (0x01<<rxBits);
				rxBits ++;
			}
			else if(count < 7*limit) /*3.5symboltime,end word */
			{
				ret++;
			}
			else if(count < 9*limit)/* 4.5symboltime, sync word*/
			{
				ret++;
			}
			else
			{ 
				ret = 0;
			}/* error */

			if(rxBits>7)
			{
				rxBits = 0;
				rxByte ++;
			}
		 }	/*end of decode */
		 return ret;
		break;
 		case E527:
 			for(count=0; count<limit; count++)
 				{
 				if(DATA_H())	
 					break;
				vDelayUs(rate);
 				}
 			if(count<limit)	//not enough
 				return(0);
 			count = (SymbolTime<<5)+(SymbolTime<<2);	//Max. Sync = 32*SymbolTime
 			count >>= 3;		//rate = 8us
 			for( ;count!=0; count--)	//sync word 0x00
 				{
 				if(DATA_H())
 					break;
 				vDelayUs(rate);
 				}
 			for( bitcnt=0;  bitcnt<((word)pklen<<3) ; bitcnt++)
 				{
 				limit = (SymbolTime<<2)+SymbolTime;	//max  = 5*SymbolTime
 				limit = limit>>3;					//rate = 8us	
 				
 				llim  = SymbolTime>>1;
 				llim  = llim>>3;					//rate = 8us, for Low Limit
 				det_h = 0;
 				det_l = 0;
 				
 				//ClrSDAT();						//for test
 				//SetSDAT();						//for test
 				
 				for(count=0; count<limit; count++)
 					{
 					if(DATA_L())
 						break;
 					vDelayUs(rate);
 					det_h++;
 					}
 				if(count>=limit)					//over 
 					return(0);
 				if(count<llim)						//no enough
 					return(0);
		 				
 				if(bitcnt==(((word)pklen<<3)-1))			//最后一位
 					{
 					for(i=0; i<(pklen-1); i++)			//shift
 						{
 						msg[i] <<= 1;
 						if(msg[i+1]&0x80)
 							msg[i] |= 0x01;
 						else
 							msg[i] |= 0x00;
 						}
 					msg[pklen-1] <<= 1;

 					if(count>((SymbolTime<<1)>>3))		//
 						msg[pklen-1] |= 0x01;
 					else
 						msg[pklen-1] |= 0x00;
 					
 					length = pklen;
 					break;
 					}
				
 				for(count=0; count<limit; count++)
 					{
 					if(DATA_H())
 						break;
 					vDelayUs(rate);
 					det_l++;
 					}
 				if(count>=limit)					//over 
 					return(0);
 				if(count<llim)						//no enough
 					return(0); 				
				
 				for(i=0; i<(pklen-1); i++)			//shift
 					{
 					msg[i] <<= 1;
 					if(msg[i+1]&0x80)
 						msg[i] |= 0x01;
 					else
 						msg[i] |= 0x00;
 					}
 				msg[pklen-1] <<= 1;
				
 				if(det_h>=det_l)
 					msg[pklen-1] |= 0x01;
 				else
 					msg[pklen-1] |= 0x00;
 				}
 			length = (bitcnt>>3);
 			break;
 		case E201:
 			for(count=0; count<limit; count++)
 				{
 				if(DATA_H())	
 					break;
				vDelayUs(rate);
 				}
 			if(count<limit)	//not enough
 				return(0);
 			count = (SymbolTime<<4)+(SymbolTime<<2);	//Max. Sync = 16*SymbolTime
 			count >>= 3;		//rate = 8us
 			for( ;count!=0; count--)
 				{
 				if(DATA_H())
 					break;
 				vDelayUs(rate);
 				}
 			for( bitcnt=0;  bitcnt<((word)pklen<<3) ; bitcnt++)
 				{
 				limit = (SymbolTime<<2);			//max  = 4*SymbolTime
 				limit = limit>>3;					//rate = 8us	
 				
 				llim  = SymbolTime>>1;
 				llim  = llim>>3;					//rate = 8us, for Low Limit
 				det_h = 0;
 				det_l = 0;
 				
 				// ClrSDAT();						//for test
 				// SetSDAT();						//for test
 				
 				for(count=0; count<limit; count++)
 					{
 					if(DATA_L())
 						break;
 					vDelayUs(rate);
 					det_h++;
 					}
 				if(count>=limit)					//over 
 					return(0);
 				if(count<llim)						//no enough
 					return(0);
		 				
 				if(bitcnt==(((word)pklen<<3)-1))			//最后一位
 					{
 					for(i=0; i<(pklen-1); i++)			//shift
 						{
 						msg[i] <<= 1;
 						if(msg[i+1]&0x80)
 							msg[i] |= 0x01;
 						else
 							msg[i] |= 0x00;
 						}
 					msg[pklen-1] <<= 1;

 					if(count>((SymbolTime<<1)>>3))		//
 						msg[pklen-1] |= 0x00;
 					else
 						msg[pklen-1] |= 0x01;
 					
 					length = pklen;
 					break;
 					}
				
 				for(count=0; count<limit; count++)
 					{
 					if(DATA_H())
 						break;
 					vDelayUs(rate);
 					det_l++;
 					}
 				if(count>=limit)					//over 
 					return(0);
 				if(count<llim)						//no enough
 					return(0); 				
				
 				for(i=0; i<(pklen-1); i++)			//shift
 					{
 					msg[i] <<= 1;
 					if(msg[i+1]&0x80)
 						msg[i] |= 0x01;
 					else
 						msg[i] |= 0x00;
 					}
 				msg[pklen-1] <<= 1;
				
 				if(det_h>=det_l)
 					msg[pklen-1] |= 0x00;
 				else
 					msg[pklen-1] |= 0x01;
 				}
 			length = (bitcnt>>3); 			
 			break;
 		default: /* ENRZ */
			// for(count=0; count<limit; count++) /* limit == Symboltime/8, 1/8 bit time */

 			for( bitcnt=0;  bitcnt<((word)pklen<<3) ;/* bitcnt++*/)
 				{
 				limit = (SymbolTime<<2)+SymbolTime;	//max  = 5*SymbolTime  
 				limit = limit/rate;					//rate = 8us	
 				
 				llim  = SymbolTime>>1;
 				llim  = llim/rate;					//rate = 8us, for Low Limit, 0.5*SymbolTime  
 				det_h = 0;
 				det_l = 0;
 				
 				if( DATA_H() ) /*data 1 */
				{
					// LED1 = 1;
					for(count=0; count<limit; count++)
						{
							
						if(DATA_L())
							break;
						vDelayUs(rate-1);
						det_h++;
						}
					if(count>=limit)					//over 
					{
						return(0);
					}
					if(count<llim)						//not enough
					{
						return(0);
					}
					/* analysis out data bits,  60 counts for one bit */
					bitTemp = ( (det_h+llim)<<3 )*rate/ SymbolTime;/* Q3 format */
					rxBits = bitTemp >> 3;
					/* write to buffer */
					
					for(i=0; i < rxBits ; i++)
 						{
							//  LED1 = 1;
							//  vDelayUs(1);
							msg[bitcnt>>3] |= 0x01<<(7 - (bitcnt%8) );/* write several bits high */
							bitcnt ++;
							// LED1 = 0;
							// vDelayUs(1);
						}
					// bitcnt +=rxBits;
				}
				else /* data 0   */
				{
					// LED1 = 1;
					for(count=0; count<limit; count++)
						{
							
						if(DATA_H())
							break;
						// LED1 = 1;
						vDelayUs(rate-1);
						// LED1 = 0;
						det_l++;
						}
					if(count>= (limit<<1 ))					//over 
						return(0);
					if(count<llim)						//no enough
						return(0); 			
					/* analysis out data bits,  60 counts for one bit */
					bitTemp = ( (det_l+llim)<<3 )*rate/ SymbolTime;/* Q3 format */
					rxBits = bitTemp >> 3;

					/* write to buffer */
					for(i=0;i<rxBits;i++)
					{
						// LED1 = 1;
						// vDelayUs(1);
						bitcnt++;
						// LED1 = 0;
						// vDelayUs(1);
					}
					// bitcnt +=rxBits;

					
					/* write to buffer */
					
					// for(i=0; i < rxBits ; i++)
 					// 	{
					// 		 msg[bitcnt>>3] &= 0xfe<<( bitcnt%8 + i );/* write several bits high */
 					// 	}	
				}

 				// for(i=0; i<(pklen-1); i++)			//shift
 				// 	{
 				// 	msg[i] <<= 1;
 				// 	if(msg[i+1]&0x80)
 				// 		msg[i] |= 0x01;
 				// 	else
 				// 		msg[i] |= 0x00;
 				// 	}
 				// msg[pklen-1] <<= 1;
				
 				// if(det_h>= llim )
 				// 	msg[i] |= 0x01;
 				// else
 				// 	msg[pklen-1] |= 0x00;
		 		// /* --------------the last bit , add bit if is 0 ---------*/		
 				// if(bitcnt==(((word)pklen<<3)-1))			//最后一位
 				// 	{
 				// 	for(i=0; i<(pklen-1); i++)			//shift
 				// 		{
 				// 		msg[i] <<= 1;
 				// 		if(msg[i+1]&0x80)
 				// 			msg[i] |= 0x01;
 				// 		else
 				// 			msg[i] |= 0x00;
 				// 		}
 				// 	msg[pklen-1] <<= 1;

 				// 	if(count>((SymbolTime<<1)>>3))		//
 				// 		msg[pklen-1] |= 0x01;
 				// 	else
 				// 		msg[pklen-1] |= 0x00;
 					
 				// 	length = pklen;
 				// 	break;
 				// 	}
				/*  ------------------------------------------------  */
 				
 				}
 			length = (bitcnt>>3);
 			break;
 		}
 	return(length);
	}
 else
 	return(0);
}
}
 
 
